#pragma once

#include <cstdint>
#include <limits>

#include "macros.h"

namespace Common {
  constexpr size_t ME_MAX_TICKERS = 8; // 交易所支持的交易标的数量上限

  constexpr size_t ME_MAX_CLIENT_UPDATES = 256 * 1024; // 撮合引擎尚未处理的全部客户端订单请求数上限，也对应订单服务器尚未发布的撮合回应数上限。
  constexpr size_t ME_MAX_MARKET_UPDATES = 256 * 1024; // 撮合引擎已生成但尚未由行情发布器发送的市场更新数量上限

  constexpr size_t ME_MAX_NUM_CLIENTS = 256; // 交易生态系统中可同时存在的市场参与者数量上限
  constexpr size_t ME_MAX_ORDER_IDS = 1024 * 1024; // 单个交易标的允许存在的订单数量上限
  constexpr size_t ME_MAX_PRICE_LEVELS = 256; // 撮合引擎维护的限价订单簿价格层级深度上限

  typedef uint64_t OrderId;
  constexpr auto OrderId_INVALID = std::numeric_limits<OrderId>::max(); // 哨兵值: 表示无效订单

  inline auto orderIdToString(OrderId order_id) -> std::string { // 日志输出
    if (UNLIKELY(order_id == OrderId_INVALID)) {
      return "INVALID";
    }

    return std::to_string(order_id);
  }

  typedef uint32_t TickerId; // 用于标识交易标的
  constexpr auto TickerId_INVALID = std::numeric_limits<TickerId>::max(); // 哨兵值

  inline auto tickerIdToString(TickerId ticker_id) -> std::string {
    if (UNLIKELY(ticker_id == TickerId_INVALID)) {
      return "INVALID";
    }

    return std::to_string(ticker_id);
  }

  typedef uint32_t ClientId; // 用于区分不同的交易参与者
  constexpr auto ClientId_INVALID = std::numeric_limits<ClientId>::max(); // 哨兵值: 表示无效的交易参与者

  inline auto clientIdToString(ClientId client_id) -> std::string {
    if (UNLIKELY(client_id == ClientId_INVALID)) {
      return "INVALID";
    }

    return std::to_string(client_id);
  }

  typedef int64_t Price; // 用于记录订单价格
  constexpr auto Price_INVALID = std::numeric_limits<Price>::max(); // 表示无效价格

  inline auto priceToString(Price price) -> std::string {
    if (UNLIKELY(price == Price_INVALID)) {
      return "INVALID";
    }

    return std::to_string(price);
  }

  typedef uint32_t Qty; // 用于表示订单数量
  constexpr auto Qty_INVALID = std::numeric_limits<Qty>::max();

  inline auto qtyToString(Qty qty) -> std::string {
    if (UNLIKELY(qty == Qty_INVALID)) {
      return "INVALID";
    }

    return std::to_string(qty);
  }

  typedef uint64_t Priority; // 表示订单在队列中的排位
  constexpr auto Priority_INVALID = std::numeric_limits<Priority>::max();

  inline auto priorityToString(Priority priority) -> std::string {
    if (UNLIKELY(priority == Priority_INVALID)) {
      return "INVALID";
    }

    return std::to_string(priority);
  }

  enum class Side : int8_t {
    INVALID = 0,
    BUY = 1,
    SELL = -1
  };

  inline auto sideToString(Side side) -> std::string {
    switch (side) {
      case Side::BUY:
        return "BUY";
      case Side::SELL:
        return "SELL";
      case Side::INVALID:
        return "INVALID";
    }

    return "UNKNOWN";
  }
}
